home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / curs_lib.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  8KB  |  368 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_menu.h"
  21. #include "mutt_curses.h"
  22.  
  23. #include <termios.h>
  24. #include <sys/types.h>
  25. #include <fcntl.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <ctype.h>
  31.  
  32. /* not possible to unget more than one char under some curses libs, and it
  33.  * is impossible to unget function keys in SLang, so roll our own input
  34.  * buffering routines.
  35.  */
  36. static short UngetCount = 0;
  37.  
  38. #define UngetBufLen 128
  39. static int UngetBuf[UngetBufLen];
  40.  
  41. void mutt_refresh (void)
  42. {
  43.   /* don't refresh in the middle of macros unless necessary */
  44.   if (!UngetCount || option (OPTFORCEREFRESH))
  45.     refresh ();
  46. }
  47.  
  48. int mutt_getch (void)
  49. {
  50.   int ch;
  51.  
  52.   if (UngetCount)
  53.     return (UngetBuf[--UngetCount]);
  54.  
  55.   Signals &= ~S_INTERRUPT;
  56.   ch = getch ();
  57.   if (Signals & S_INTERRUPT)
  58.     mutt_query_exit ();
  59.   return (ch == ctrl ('G') ? ERR : ch);
  60. }
  61.  
  62. int mutt_get_field (char *field, char *buf, size_t buflen, int complete)
  63. {
  64.   int ret;
  65.   int len = strlen (field); /* in case field==buffer */
  66.  
  67.   do
  68.   {
  69.     CLEARLINE (LINES-1);
  70.     addstr (field);
  71.     mutt_refresh ();
  72.     ret = mutt_enter_string ((unsigned char *) buf, buflen, LINES-1, len, complete);
  73.   }
  74.   while (ret == 1);
  75.   CLEARLINE (LINES-1);
  76.   return (ret);
  77. }
  78.  
  79. int mutt_get_password (char *msg, char *buf, size_t buflen)
  80. {
  81.   int rc;
  82.  
  83.   CLEARLINE (LINES-1);
  84.   addstr (msg);
  85.   rc = mutt_enter_string ((unsigned char *) buf, buflen, LINES - 1, strlen (msg), M_PASS);
  86.   CLEARLINE (LINES-1);
  87.   return (rc);
  88. }
  89.  
  90. void mutt_clear_error (void)
  91. {
  92.   Errorbuf[0] = 0;
  93.   CLEARLINE (LINES-1);
  94. }
  95.  
  96. #ifdef AMIGA
  97. char * MakeAmiga(const char *str)
  98. {
  99.   /* Make a unix-style "/path/to/some/file" an amiga-style:
  100.    * "path:to/some/file".
  101.    * This is neccessary when calling an external file (the editor),
  102.    * as it probably would not understand unix-style paths
  103.    */
  104.  
  105.   char *w, *x;
  106.  
  107.   if (str[0] != '/')
  108.     return strdup(str);
  109.  
  110.   w = strdup((char *)(str+1));
  111.   x=strchr(w,'/');
  112.   if (x)
  113.     *x=':';
  114.  
  115.   return w;
  116. }
  117. #endif
  118.  
  119. void mutt_edit_file (const char *editor, const char *data)
  120. {
  121.   char cmd[LONG_STRING];
  122.  
  123.   endwin ();
  124. #ifdef AMIGA
  125.   mutt_expand_fmt (cmd, sizeof (cmd), editor, MakeAmiga(data));
  126. #else
  127.   mutt_expand_fmt (cmd, sizeof (cmd), editor, data);
  128. #endif
  129.   mutt_system (cmd);
  130.   keypad (stdscr, TRUE);
  131.   clearok (stdscr, TRUE);
  132. }
  133.  
  134. int mutt_yesorno (const char *msg, int def)
  135. {
  136.   int ch;
  137.  
  138.   CLEARLINE(LINES-1);
  139.   printw("%s: [%c] ", msg, def ? 'y' : 'n');
  140.   FOREVER
  141.   {
  142.     mutt_refresh ();
  143.     ch = mutt_getch ();
  144.     if (ch == ERR) return(-1);
  145.     if (CI_is_return (ch))
  146.       break;
  147.     else if (ch == 'y')
  148.     {
  149.       def = 1;
  150.       break;
  151.     }
  152.     else if (ch == 'n')
  153.     {
  154.       def = 0;
  155.       break;
  156.     }
  157.     else
  158.     {
  159.       BEEP();
  160.     }
  161.   }
  162.   addstr (def ? "Yes" : "No");
  163.   mutt_refresh ();
  164.   return (def);
  165. }
  166.  
  167. /* this function is called when the user presses the abort key */
  168. void mutt_query_exit (void)
  169. {
  170.   mutt_flushinp ();
  171.   curs_set (1);
  172.   if (Timeout)
  173.     timeout (-1); /* restore blocking operation */
  174.   if (mutt_yesorno ("Exit Mutt?", 1) == 1)
  175.   {
  176.     endwin ();
  177.     exit (0);
  178.   }
  179.   mutt_curs_set (-1);
  180.   Signals &= ~S_INTERRUPT;
  181. }
  182.  
  183. void mutt_error (const char *fmt, ...)
  184. {
  185.   va_list ap;
  186.  
  187.   va_start (ap, fmt);
  188.   vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
  189.   va_end (ap);
  190.   
  191.   Errorbuf[ (COLS < sizeof (Errorbuf) ? COLS : sizeof (Errorbuf)) - 2 ] = 0;
  192.  
  193.   BEEP ();
  194.   SETCOLOR (MT_COLOR_ERROR);
  195.   mvaddstr (LINES-1, 0, Errorbuf);
  196.   clrtoeol ();
  197.   SETCOLOR (MT_COLOR_NORMAL);
  198.   mutt_refresh ();
  199.  
  200.   set_option (OPTMSGERR);
  201. }
  202.  
  203. void mutt_message (const char *fmt, ...)
  204. {
  205.   va_list ap;
  206.  
  207.   va_start (ap, fmt);
  208.   vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
  209.   va_end (ap);
  210.  
  211.   Errorbuf[ (COLS < sizeof (Errorbuf) ? COLS : sizeof (Errorbuf)) - 2 ] = 0;
  212.  
  213.   SETCOLOR (MT_COLOR_MESSAGE);
  214.   mvaddstr (LINES - 1, 0, Errorbuf);
  215.   clrtoeol ();
  216.   SETCOLOR (MT_COLOR_NORMAL);
  217.   mutt_refresh ();
  218.  
  219.   unset_option (OPTMSGERR);
  220. }
  221.  
  222. void mutt_show_error (void)
  223. {
  224.   SETCOLOR (option (OPTMSGERR) ? MT_COLOR_ERROR : MT_COLOR_MESSAGE);
  225.   CLEARLINE (LINES-1);
  226.   addstr (Errorbuf);
  227.   SETCOLOR (MT_COLOR_NORMAL);
  228. }
  229.  
  230. void mutt_endwin (const char *msg)
  231. {
  232.   move (LINES-1, COLS-1);
  233.   attrset (A_NORMAL);
  234.   mutt_refresh ();
  235.   endwin ();
  236.   if (msg)
  237.   {
  238.     fputc ('\n', stdout);
  239.     puts (msg);
  240.   }
  241. }
  242.  
  243. void mutt_perror (const char *s)
  244. {
  245.   char *p = strerror (errno);
  246.  
  247.   mutt_error ("%s: %s (errno = %d)", s, p ? p : "unknown error", errno);
  248. }
  249.  
  250. int mutt_any_key_to_continue (const char *s)
  251. {
  252.   struct termios t;
  253.   struct termios old;
  254.   int f, ch;
  255.  
  256.   f = open ("/dev/tty", O_RDONLY);
  257.   tcgetattr (f, &t);
  258.   memcpy ((void *)&old, (void *)&t, sizeof(struct termios)); /* save original state */
  259.   t.c_lflag &= ~(ICANON | ECHO);
  260.   t.c_cc[VMIN] = 1;
  261.   t.c_cc[VTIME] = 0;
  262.   tcsetattr (f, TCSADRAIN, &t);
  263.   fflush (stdout);
  264.   if (s)
  265.     fputs (s, stdout);
  266.   else
  267.     fputs ("Press any key to continue...", stdout);
  268.   fflush (stdout);
  269.   ch = fgetc (stdin);
  270.   fflush (stdin);
  271.   tcsetattr (f, TCSADRAIN, &old);
  272.   close (f);
  273.   fputs ("\r\n", stdout);
  274.   return (ch);
  275. }
  276.  
  277. int mutt_do_pager (char *banner, char *tempfile, int do_color)
  278. {
  279.   int rc;
  280.  
  281.   if (strcmp (Pager, "builtin") == 0)
  282.     rc = mutt_pager (banner, tempfile, NULL, do_color);
  283.   else
  284.   {
  285.     char cmd[STRING];
  286.     
  287.     endwin ();
  288.     snprintf (cmd, sizeof (cmd), "%s %s", Pager, tempfile);
  289.     mutt_system (cmd);
  290.     mutt_unlink (tempfile);
  291.     rc = 0;
  292.   }
  293.  
  294.   return rc;
  295. }
  296.  
  297. int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw)
  298. {
  299.   int i;
  300.  
  301.   mvaddstr (LINES-1, 0, (char *) prompt);
  302.   addstr (" ('?' for list): ");
  303.   if (buf[0])
  304.     addstr (buf);
  305.   clrtoeol ();
  306.   mutt_refresh ();
  307.  
  308.   if ((i = mutt_getch ()) == ERR)
  309.   {
  310.     CLEARLINE (LINES-1);
  311.     return (-1);
  312.   }
  313.   else if (i == '?')
  314.   {
  315.     mutt_refresh ();
  316.     buf[0] = 0;
  317.     mutt_select_file (buf, blen, 0);
  318.     *redraw = REDRAW_FULL;
  319.   }
  320.   else
  321.   {
  322.     char *pc = safe_malloc (strlen (prompt) + 3);
  323.  
  324.     sprintf (pc, "%s: ", prompt);
  325.     mutt_ungetch (i);
  326.     if (mutt_get_field (pc, buf, blen, M_EFILE | M_CLEAR) != 0)
  327.       buf[0] = 0;
  328.     MAYBE_REDRAW (*redraw);
  329.     free (pc);
  330.   }
  331.  
  332.   return 0;
  333. }
  334.  
  335. /* FOO - this could be made more efficient by allocating/deallocating memory
  336.  * instead of using a fixed array
  337.  */
  338. void mutt_ungetch (int ch)
  339. {
  340.   if (UngetCount < UngetBufLen) /* make sure not to overflow */
  341.     UngetBuf[UngetCount++] = ch;
  342. }
  343.  
  344. void mutt_flushinp (void)
  345. {
  346.   UngetCount = 0;
  347.   flushinp ();
  348. }
  349.  
  350. #if (defined(USE_SLANG_CURSES) || defined(HAVE_CURS_SET))
  351. /* The argument can take 3 values:
  352.  * -1: restore the value of the last call
  353.  *  0: make the cursor invisible
  354.  *  1: make the cursor visible
  355.  */
  356. void mutt_curs_set (int cursor)
  357. {
  358.   static int SavedCursor = 1;
  359.   
  360.   if (cursor < 0)
  361.     cursor = SavedCursor;
  362.   else
  363.     SavedCursor = cursor;
  364.   
  365.   curs_set (cursor);
  366. }
  367. #endif
  368.